package com.yq.ylmall.wechat.controller;

import com.google.gson.Gson;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.yq.ylmall.dto.order.OrderInfoDto;
import com.yq.ylmall.result.Result;
import com.yq.ylmall.utils.HttpUtil;
import com.yq.ylmall.wechat.entity.RefundReason;
import com.yq.ylmall.wechat.service.WechatPayService;
import com.yq.ylmall.wechat.utils.WechatPay2ValidatorForRequest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Project: yourlife
 * @Name: WechatController
 * @Author: Jack_Li
 * @Date: 2024/6/13 15:37
 */

@Api(tags = "微信支付接口")
@RestController
@RequestMapping("/api/payment/wechat")
@Slf4j
public class WechatController {

    @Resource
    private WechatPayService wechatPayService;

    @Resource
    private Verifier verifier;

//    @ApiOperation("调用统一下单API，生成支付二维码")
//    @PostMapping("/native/{orderNo}")
//    public Result nativePay(@PathVariable("orderNo") String orderNo) throws IOException {
//      log.info("发起支付请求订单编号: {}", orderNo);
//      // 返回支付二维码连接和订单号
//      Map<String, Object> map = wechatPayService.nativePay(orderNo);
//
//      return Result.ok(map);
//    }

    @ApiOperation("调用统一下单API，生成支付二维码")
    @PostMapping("/native")
    public Result nativePay(@RequestBody OrderInfoDto orderInfoDto) throws IOException {
      log.info("发起支付请求订单: {}", orderInfoDto);
      // 返回支付二维码连接和订单号
      Map<String, Object> map = wechatPayService.nativePay(orderInfoDto);

      return Result.ok(map);
    }

    @ApiOperation("接收微信支付异步通知")
    @PostMapping("/native/notify")
    public String nativeNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("接收微信支付异步通知");
        Gson gson = new Gson();
        HashMap<String, Object> map = new HashMap<>();
        String body = HttpUtil.readData(request);
        try {
            // 处理通知参数
            Map<String, Object> bodyMap = gson.fromJson(body, Map.class);
            String requestId = (String) bodyMap.get("id");
            log.info("微信支付通知: {}", requestId);
            log.info("微信支付通知: {}", body);

            // 签名认证
            WechatPay2ValidatorForRequest validator = new WechatPay2ValidatorForRequest(verifier, body, requestId);
            if (!validator.validate(request)) {
                log.info("签名认证失败");
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "失败");
                return gson.toJson(map);
            }
            // 订单处理
            wechatPayService.processOrder(bodyMap);

            // 成功应答
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }
    }

    /**
     * 取消订单
     * @param orderNo
     * @return
     * @throws Exception
     */
    @ApiOperation("取消订单")
    @PostMapping("/cancel/{orderNo}")
    public Result cancelOrder(@PathVariable("orderNo") String orderNo) throws Exception {
        wechatPayService.cancelOrder(orderNo);
        return Result.ok();
    }

    /**
     * 查询订单
     * @param orderNo
     * @return
     * @throws Exception
     */
    @ApiOperation("查询订单")
    @GetMapping("/query/{orderNo}")
    public Result queryOrder(@PathVariable("orderNo") String orderNo) throws Exception {
        String result = wechatPayService.queryOrder(orderNo);

        return Result.ok(result);
    }

    @ApiOperation("申请退款")
    @PostMapping("/refund")
    public Result refund(@RequestBody RefundReason reason) throws Exception {
        log.info("发起退款请求: {}", reason);
        wechatPayService.refund(reason);
        return Result.ok();
    }

    @ApiOperation("查询退款")
    @GetMapping("/query/refund/{orderNo}")
    public Result queryRefund(@PathVariable("orderNo") String orderNo) throws Exception {
        String result = wechatPayService.queryRefund(orderNo);

        return Result.ok(result);
    }

    @ApiOperation("退款回调")
    @PostMapping("/refund/notify")
    public String refundNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("退款回调");
        Gson gson = new Gson();
        Map<String, Object> map = new HashMap<>();

        try {
            String body = HttpUtil.readData(request);
            Map<String, Object> bodyMap = gson.fromJson(body, Map.class);
            String requestId = (String) bodyMap.get("id");

            WechatPay2ValidatorForRequest validator = new WechatPay2ValidatorForRequest(verifier, body, requestId);
            if (!validator.validate(request)) {
                log.info("签名认证失败");
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "通知验签失败");
                return gson.toJson(map);
            }

            // 退款处理
            wechatPayService.processRefund(bodyMap);

            // 成功应答
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "成功");
            return gson.toJson(map);
        } catch (Exception e) {
            e.printStackTrace();
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "失败");
            return gson.toJson(map);
        }
    }
}
